package {
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.text.StyleSheet;
	import flash.utils.Dictionary;
	import flash.utils.Timer;
	
	import com.passioneffect.collection.Collection;
	import com.passioneffect.collection.Iterator;
	import com.passioneffect.components.FlowEffect;
	import com.passioneffect.components.Tooltip;
	import com.passioneffect.display.Component;
	import com.passioneffect.layoutflow.SimpleLayoutFlow;
	import com.passioneffect.parser.ListXMLParser;
	import com.passioneffect.parser.ValuePairParser;
	import com.passioneffect.scroll.ScrollHandler;
	
	import Boolean;
	import Boolean;
	import Number;
	import Number;
	import gs.TweenMax;	

	/**
	 * @author Passion Effect
	 */
	public class SuperCarouselV2 extends FlowEffect {
		
		[Inspectable(category="a1",type=Number,defaultValue=200)]
		public var thumbnailWidth:Number=200;
		
		[Inspectable(category="a2",type=Number,defaultValue=200)]
		public var thumbnailHeight:Number=200;
		
		[Inspectable(category="b1",type=Number,defaultValue=0.5)]
		public var thumbnailAlignY:Number=0.5; //center,top,left,right,bottom
		
		[Inspectable(category="b2",type=Number,defaultValue=0.5)]
		public var thumbnailAlignX:Number=0.5;
		
		[Inspectable(category="b3",type=Number,defaultValue=0.5)]
		public var minScale:Number=0.5;
		
		[Inspectable(category="b4",type=Number,defaultValue=1)]
		public var maxScale:Number=1;
		
		[Inspectable(category="b5",type=Number,defaultValue=0)]
		public var minBrightness:Number=0;
		
		[Inspectable(category="b6",type=Number,defaultValue=1)]
		public var maxBrightness:Number=1;
		
		[Inspectable(category="b7",type=Number,defaultValue=200)]
		public var radiusX:Number=200;
		
		[Inspectable(category="b8",type=Number,defaultValue=0)]
		public var radiusY:Number=0;
		
		[Inspectable(category="b9",type=Number,defaultValue=7)]
		public var blurScale:Number=7;
		
		public var centerItems:Collection;
		public var stayCenter:Dictionary;
		
		protected var _reflection:Boolean=true;
		
		[Inspectable(category="b12",type=Number,defaultValue=150)]
		public var reflectionRatio:Number=150;
		
		[Inspectable(category="b13",type=Number,defaultValue=0.5)]
		public var reflectionAlpha:Number=0.5;
		
		[Inspectable(category="b14",type=Number,defaultValue=0)]
		public var reflectionDistance:Number=0;
		
		[Inspectable(category="b15",type=Color,defaultValue="#3333cc")]
		public var mouseOverBorderColor:Number=0x3333CC;
		
		[Inspectable(category="b16",type=Number,defaultValue=0.3)]
		public var highlightDarken:Number=0.3;
		
		[Inspectable(category="b17",type=Number,defaultValue=0)]
		public var centerX:Number=0;
		
		[Inspectable(category="b18",type=Number,defaultValue=0)]
		public var centerY:Number=0;
		
		public var styleSheet:StyleSheet;
		
		[Inspectable(category="b19",type=Boolean,defaultValue=true)]
		public var dragX:Boolean=true;
		
		[Inspectable(category="b20",type=Boolean,defaultValue=true)]
		public var dragY:Boolean=true;
		
		private var downPoint : Point;
		private var sx : Number;
		private var sy : Number;
		public var dragging : Boolean;
		
		private var ox : Number;
		private var dmx : Number;
		private var changeX;
		private var dragTimer : Timer;
		private var carouselLayout : CarouselLayout;
		public var defaultType : String="carousel";
		private var mc:MovieClip;
		
		[Inspectable(type=Number,defaultValue=1)]
		public var tooltipDelay:Number=1;
		
		[Inspectable(type=Number,defaultValue=0)]
		public var tooltipWidth:Number=0;
		
		[Inspectable(type=Number,defaultValue=20)]
		public var tooltipDistance:Number=20;
		
		[Inspectable(type=List,enumeration="top,bottom,left,right",defaultValue="top")]
		public var tooltipPosition:String="top";
		
		[Inspectable(type=Color,defaultValue="#ffffff")]
		public var tooltipTextColor:uint=0xffffff;
		
		[Inspectable(type=Color,defaultValue="#000000")]
		public var tooltipBgColor:uint=0x000000;
		
		[Inspectable(type="Font Name",defaultValue="Arial")]
		public var tooltipFont:String="Arial";
		
		[Inspectable(type=Number,defaultValue=20)]
		public var tooltipFontSize:Number=20;
		
		[Inspectable(type=Boolean,defaultValue=false)]
		public var tooltipEmbedFonts:Boolean=false;
		
		[Inspectable(type=Boolean,defaultValue=true)]
		public var mouseScroll:Boolean=true;
		
		[Inspectable(type=Number,defaultValue=0.2)]
		public var rotateSpeed : Number=0.2;
		
		[Inspectable(type=Boolean,defaultValue=true)]
		public var border:Boolean=true;
		
		private var content:CarouselContent;
		
		public function SuperCarouselV2(parentComponent : Component = null) {
			super(parentComponent);
		}
		
		override protected function preset():void{
			_defaultIndex=-1;
			_direction = "horizontal";
			_type="carousel";
			_contentClass="carouselContentMC";
			//scrollFunction=DirectionScroll.scroll;
			//scrollFunction=ScrollHandler.scroll;
			layout=new CarouselLayout(this);			
			
			layoutFlow = new SimpleLayoutFlow();
			xmlParser = new ListXMLParser();
			styleXMLParser = new ValuePairParser();
			
			Tooltip.init(stage);
			
		}
		
		public function scrollToAngle(angle:Number):void{
			scrollToLengthX(angle);
		}
		
		public function get tooltipStyle():Object{
			return {delay:tooltipDelay,width:tooltipWidth,distance:tooltipDistance,position:tooltipPosition,color:tooltipTextColor,backgroundColor:tooltipBgColor,font:tooltipFont,fontSize:tooltipFontSize,embedFonts:tooltipEmbedFonts};
		}
		
		override protected function postset() : void {
			selectIndex(defaultIndex);
		}

		private function cssLoaded(event : Event) : void {
			styleSheet = new StyleSheet();
   			styleSheet.parseCSS(event.target.data);
		}

		public function toRadiusX(r:Number):void{
			TweenMax.to(this,_scrollTime,{radiusX:r});
		}
		
		public function toRadiusY(r:Number):void{
			TweenMax.to(this,_scrollTime,{radiusY:r});
		}
		
		override public function setMouseEvents() : void {
			super.setMouseEvents();
			stage.addEventListener(MouseEvent.MOUSE_DOWN, downHandler);
			
			if(mouseScroll){
				this.addEventListener(Event.ENTER_FRAME,enterScroll);
			}
		}
		
		private function enterScroll(evt:Event) : void {
			DirectionScroll.scroll(this);
		}

		private function downHandler(event : MouseEvent) : void {
			if(!hitTest())return;
			TweenMax.killTweensOf(_layout, false);
			
			downPoint = new Point(mouseX, mouseY);
			sx = layout.scrollValueX;
			sy=layout.scrollValueY;
			
			ox=getMouseX();
			
			stage.addEventListener(MouseEvent.MOUSE_MOVE, dragHandler);
			stage.addEventListener(MouseEvent.MOUSE_UP, removeDragHandler);
			
			dragTimer=new Timer(100);
			dragTimer.addEventListener(TimerEvent.TIMER,oxHandler);
			dragTimer.start();
			
		}
		
		private function oxHandler(event : TimerEvent) : void {
			ox=getMouseX();
		}

		private function getMouseX():Number{
			if(direction=="horizontal"){
				return mouseX;
			}else{
				return mouseY;
			}
		}

		private function removeDragHandler(event : MouseEvent) : void {
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, dragHandler);
		}

		private function undragHandler(event : MouseEvent) : void {
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, dragHandler);
			stage.removeEventListener(MouseEvent.MOUSE_UP, undragHandler);
			doLater(unsetDragging);
		}

		private function unsetDragging() : void {
			dragging = false;
			dmx = ox - getMouseX();
			if(changeX>0){
				dmx+=5;
			}else if(changeX<0){
				dmx-=5;
			}
			
			if(dragX)TweenMax.to(layout, 1, {onUpdate:invalidate, scrollValueX:String(dmx * 2)});
			dmx = 0;
			dragTimer.stop();
			dragTimer.removeEventListener(TimerEvent.TIMER,oxHandler);
			dragTimer=null;
		}

		private function dragHandler(event : MouseEvent) : void {

			var dx : Number;
			var dy : Number;
			if(direction=="horizontal"){
				dx = mouseX - downPoint.x;
				dy = mouseY - downPoint.y;
			}else{
				dy = downPoint.x-mouseX;
				dx = mouseY - downPoint.y;
			}
			
			changeX=-dx*0.3;
			
			if(Math.abs(changeX)>3||Math.abs(dy)>3){
				dragging = true;
				unselect();
				TweenMax.killTweensOf(_layout, false);
				stage.addEventListener(MouseEvent.MOUSE_UP, undragHandler);
				
				if(dragX)layout.scrollValueX = sx+changeX;
				if(dragY)layout.scrollValueY = sy + dy;
				invalidate();
			}
			
			
		}
		
		override public function setSize(w:Number,h:Number):void{
			super.setSize(w,h);
			if(scrollTargetItem) {
				scrollToItem(scrollTargetItem);
			}
			if(centerItems){
				var itr:Iterator=centerItems.iterator();
				var item : DisplayObject;
				
				while(itr.hasNext()){
					item=DisplayObject(itr.next());
					if(stayCenter[item]){
						item.x=compWidth/2-item.width/2;
						item.y=compHeight/2-item.height/2;
					}
				}
			}
		}
		
		public function addCenterItem(obj:DisplayObject,center:Boolean=false):void{
			if(centerItems==null){
				centerItems=new Collection();
				stayCenter=new Dictionary(true);
			}
			if(!centerItems.contains(obj)){
				centerItems.addItem(obj);
				stayCenter[obj]=center;
			}
		}
		
		public function removeCenterItem(obj:DisplayObject):void{
			if(!centerItems.contains(obj)){
				centerItems.removeItem(obj);
				delete stayCenter[obj];
			}
		}
		
		[Inspectable(category="b11",type=Boolean,defaultValue="true")]
		public function get reflection() : Boolean {
			return _reflection;
		}
		
		public function set reflection(reflection : Boolean) : void {
			_reflection = reflection;
			dispatchChangeSetting("reflection", reflection);
		}
	}
}
